package jinyilw.common.app;

import jinyilw.common.ExecuteTools;
import jinyilw.common.OSTools;
import jinyilw.common.Operator;
import jinyilw.common.file.FileTools;
import jinyilw.common.log.LogTools;

import java.io.File;
import java.util.ArrayList;

public class AppConfig
{
	private static final ArrayList<Operator<?>> appExitingOperators = new ArrayList<>();
	private static final ArrayList<Operator<?>> appExitedOperators = new ArrayList<>();

	public static int appVersion = 1;
	public static String appName = "Jinyi_JavaApp";
	public static String exeFileName = "JavaApp.jar";
	public static boolean isJarFile = true;
	public static String settingsFolderName = "";
	public static String appSettingsFileName = "JavaApp.ini";
	public static String splashPicture = "splash.jpg";

	private static String appDataPath;
	private static File appDataFolder;
	private static File appExeFile;
	private static File settingsFolder;
	private static File appSettingsFile;
	public static String updateScriptForWin;
	public static String updateScriptForOther;

	private static boolean restart, update;

	static
	{
		getUpdateScript();
		ExecuteTools.exeWhenExitApp(() -> {
			{
				executeApplicationExiting();
				executeApplicationExited();
				if (update)
				{
					if (OSTools.isWindows())
					{
						ExecuteTools.exeCmd(updateScriptForWin);
					} else
					{
						ExecuteTools.exeBash(updateScriptForOther);
					}
				} else if (restart)
				{
					File appFile = getAppExeFile();
					if (isJarFile)
						ExecuteTools.exeJarFile(appFile, splashPicture);
					else
						ExecuteTools.exeFile(appFile);
				}
			}
		});
	}

	private AppConfig()
	{
	}

	public static void set(int appVersion, String appName, String exeFileName,
			String settingsFolderName,
			String appSettingsFileName, String splashPicture)
	{
		AppConfig.appVersion = appVersion;
		AppConfig.appName = appName;
		AppConfig.exeFileName = exeFileName;
		AppConfig.isJarFile = exeFileName.endsWith(".jar");
		AppConfig.settingsFolderName = settingsFolderName;
		AppConfig.appSettingsFileName = appSettingsFileName;
		AppConfig.splashPicture = splashPicture;
		getUpdateScript();
	}

	private static void getUpdateScript()
	{
		String script = isJarFile ? ExecuteTools.getJavaBinPath()
				+ " -splash:" + splashPicture
				+ " -jar " + exeFileName : exeFileName;
		updateScriptForWin =
				"@ping 127.0.0.1 -n 3 && move tmp\\" + exeFileName + " " + exeFileName + "&&"
						+ script;
		updateScriptForOther =
				"mv tmp/" + exeFileName + " " + exeFileName + "&&" + script;
	}

	public static void setAppName(String name)
	{
		appName = name;
	}

	public static void setExeFileName(String fileName)
	{
		exeFileName = fileName;
		appExeFile = null;
		getUpdateScript();
	}

	public static void setRestart(boolean restart)
	{
		AppConfig.restart = restart;
	}
	public static void setUpdate(boolean update)
	{
		AppConfig.update = update;
	}

	public static String getAppDataPath()
	{
		if (appDataPath == null)
			appDataPath = getAppDataFolder().getAbsolutePath();
		return appDataPath;
	}

	public static File getAppDataFolder()
	{
		if (appDataFolder == null)
		{
			appDataFolder = new File(FileTools.getUserDocuments(), appName);
			appDataFolder.mkdirs();
		}
		return appDataFolder;
	}

	public static File getAppExeFile()
	{
		if (appExeFile == null)
			appExeFile = FileTools.getUserFile(exeFileName);
		return appExeFile;
	}

	public static File getSettingsFolder()
	{
		if (settingsFolder == null)
		{
			settingsFolder = FileTools.createDirectory(settingsFolderName);
			if (!FileTools.canWrite(settingsFolder))
				settingsFolder = FileTools.createDirectory(
						new File(getAppDataFolder(), settingsFolderName));
		}
		return settingsFolder;
	}

	public static File getAppSettingsFile()
	{
		if (appSettingsFile == null)
			appSettingsFile = new File(getSettingsFolder(), appSettingsFileName);
		return appSettingsFile;
	}

	public static void restartAppToUpdate()
	{
		update = true;
		System.exit(0);
	}

	public static void addAppExitingOperator(Operator<?> operator)
	{
		appExitingOperators.add(operator);
	}

	public static void addAppExitedOperator(Operator<?> operator)
	{
		appExitedOperators.add(operator);
	}

	public static void executeApplicationExiting()
	{
		for (Operator<?> operator : appExitingOperators)
			operator.run();
	}

	public static void executeApplicationExited()
	{
		for (Operator<?> operator : appExitedOperators)
			operator.run();
	}

	public static void restartApp()
	{
		File appFile = getAppExeFile();
		if (appFile == null || !appFile.exists())
		{
			LogTools.warn("重启失败，找不到应用程序！");
			return;
		}
		restart = true;
		System.exit(0);
	}
}
